package lesson24;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MyConditionQueue {

    private Queue queue;

    private int max;

    private ReentrantLock lock = new ReentrantLock();

    private Condition notEmpty = lock.newCondition();

    private Condition notFull = lock.newCondition();

    private static AtomicInteger count = new AtomicInteger();

    public MyConditionQueue(int max){
        this.max = max;
        this.queue = new ArrayBlockingQueue(max);
    }

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        MyConditionQueue myConditionQueue = new MyConditionQueue(10);

        executorService.execute(() -> {
            while (true){
                myConditionQueue.put();
            }
        });


        executorService.execute(() -> {
            while (true){
                myConditionQueue.take();
            }
        });

    }

    public void put(){
        lock.lock();
        try {
            while (queue.size() == max){
                System.out.println("queue size : "+ queue.size() + " 队列已满。。。");
                notFull.await();
            }
            queue.offer(count.get());
            System.out.println("queue put : " + count.getAndIncrement());
            notEmpty.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void take(){
        lock.lock();
        try {
            while (queue.size() == 0){
                System.out.println("queue size : " + queue.size() + " 队列已空。。。");
                notEmpty.await();
            }
            System.out.println("query take : " +queue.poll());
            notFull.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}
